using System.Collections.Generic;
using UniFramework.Actor;
using UniFramework.Buff;
using UnityEngine;

namespace UniFramework.Battle
{
	public class DamageSystem : MonoBehaviour
	{
		private List<DamageInfo> _damageInfoList = new List<DamageInfo>();

		public void OnLogicFrameUpdate()
		{
			int i = 0;
			while (i < _damageInfoList.Count)
			{
				DealWithDamage(_damageInfoList[i]);
				_damageInfoList.RemoveAt(0);
			}
		}

		private void DealWithDamage(DamageInfo dInfo)
		{
			if (!dInfo.target) return;
			if (dInfo.target.isDead) return;
			BuffSystem attackBuffSystem = null;
			BuffSystem targetBuffSystem = null;
			//当前攻击去遍历攻击者有的buff，看是否需要改变当前攻击
			if (dInfo.attacker && !dInfo.attacker.isDead)
			{
				attackBuffSystem = dInfo.attacker.GetComponent<BuffSystem>();
				if (attackBuffSystem.IsInit)
				{
					var list = attackBuffSystem.BuffList;
					foreach (var buff in list) buff.buffConfig.onHit?.Invoke(buff, ref dInfo, dInfo.target);
				}
			}

			//遍历一遍被攻击者的buff
			targetBuffSystem = dInfo.target.GetComponent<BuffSystem>();
			if (targetBuffSystem.IsInit)
			{
				var list = targetBuffSystem.BuffList;
				foreach (var buff in list) buff.buffConfig.onBeHurt?.Invoke(buff, ref dInfo, dInfo.attacker);
			}

			//扣血
			LogicActorProperty property = dInfo.target.GetComponent<LogicActorState>().property;
			property.hp -= dInfo.damage.damageValue;
			bool isDead = property.hp <= 0;
			dInfo.target.isDead = isDead;
			dInfo.target.OnBeHit(dInfo);

			//判断角色是否会被杀死，再走下buff接口
			if (isDead)
			{
				if (dInfo.attacker && !dInfo.attacker.isDead)
				{
					attackBuffSystem ??= dInfo.attacker.GetComponent<BuffSystem>();
					if (attackBuffSystem.IsInit)
					{
						var list = attackBuffSystem.BuffList;
						foreach (var buff in list) buff.buffConfig.onKill?.Invoke(buff, dInfo, dInfo.target);
					}
				}

				if (targetBuffSystem.IsInit)
				{
					var list = targetBuffSystem.BuffList;
					foreach (var buff in list) buff.buffConfig.onBeKilled?.Invoke(buff, dInfo, dInfo.attacker);
				}
			}

			//伤害流程走完，添加buff
			if (dInfo.addBuffList != null)
			{
				foreach (var addBuff in dInfo.addBuffList)
				{
					LogicActor toActor = addBuff.target;
					BuffSystem buffSystem = toActor.Equals(dInfo.attacker) ? attackBuffSystem : targetBuffSystem;
					if (buffSystem != null && buffSystem.IsInit)
					{
						buffSystem.AddBuff(addBuff);
					}
				}
			}

			//所有buff处理完成去调用死亡接口
			if(isDead) dInfo.target.OnDie();
		}

		/// <summary>
		/// 外部产生伤害的接口
		/// </summary>
		/// <param name="attacker"></param>
		/// <param name="target"></param>
		/// <param name="damage"></param>
		/// <param name="tags"></param>
		public void DoDamage(LogicActor attacker, LogicActor target, Damage damage, EDamageInfoTag[] tags = null)
		{
			_damageInfoList.Add(new DamageInfo(attacker, target, damage, tags));
		}
	}
}